learning, development, azure, dotnet, conference, documentation
Using HTTP Files for API Testing
HTTP files are a great way to test your web API calls directly from your code editor, offering a lightweight alternative to Postman. They’re especially helpful for documenting and version-controlling your API tests alongside your code.
Table of Contents
- Getting Started with HTTP Files
- Advanced Features
- Benefits Over Postman
- Azure AD Authentication for Protected APIs
- Method 1: Client Credentials Flow (Service-to-Service)
- Method 2: Authorization Code Flow with PKCE (Interactive)
- Method 3: Using REST Client’s Built-in Azure AD Support
- Method 4: Environment-Specific Configuration
- Method 5: Token Refresh Pattern
- Security Best Practices
- Common Token Response Structure
- References
- Appendixes
Getting Started with REST Client
.http Files
1. Install the REST Client
Extension in VS Code
First, install the REST Client
extension by Huachao Mao:
- Open VS Code
- Go to Extensions (Ctrl+Shift+X)
- Search for
REST Client
- Click
Install
2. Create an HTTP File
Create a new file with .http
or .rest
extension in your project:
3. Write Your First HTTP Request
Here’s a simple GET request:
### Get all items
GET https://api.example.com/items
4. Add Headers and Body
For a POST request with JSON body:
### Create new item
POST https://api.example.com/items
Content-Type: application/json
{
"name": "New Item",
"description": "This is a test item"
}
5. Execute Requests
To execute a request: - Click the Send Request
link that appears above each request - Or use the shortcut Ctrl+Alt+R
(Windows/Linux) or Cmd+Alt+R
(Mac)
Advanced Features
Variables and Environments
Define variables with @
to reuse values. Variables can be organized in multiple ways depending on your needs:
1. Inline Variables (Same File)
Define variables directly in your HTTP file:
@baseUrl = https://api.example.com
@authToken = Bearer your-token-here
### Get all items
GET {{baseUrl}}/items
Authorization: {{authToken}}
2. Variable Organization in Same File
For better organization, group variables at the top of your HTTP file:
api-tests.http
:
### Variables section
@baseUrl = https://api.example.com
@version = v1
@contentType = application/json
### Get all items
GET {{baseUrl}}/{{version}}/items
Content-Type: {{contentType}}
### Create new item
POST {{baseUrl}}/{{version}}/items
Content-Type: {{contentType}}
{
"name": "Test Item"
}
3. Environment-Specific Files (Not Version Controlled)
Create environment-specific variable files that contain sensitive or environment-specific data. Add these to .gitignore
to keep them out of version control:
.gitignore
:
# HTTP file environment variables
*.env.http
.env.*.http
secrets.http
local-variables.http
dev.env.http
(not versioned):
@baseUrl = https://localhost:7001
@clientSecret = dev-secret-key
@dbConnectionString = Server=localhost;Database=DevDB
prod.env.http
(not versioned):
@baseUrl = https://api.production.com
@clientSecret = prod-secret-key
@dbConnectionString = Server=prod-server;Database=ProdDB
api-tests.http
(versioned):
### Copy variables from dev.env.http manually when needed
@baseUrl = https://localhost:7001
@clientSecret = dev-secret-key
### Shared variables that can be version controlled
@apiVersion = v2
@userAgent = MyApp/1.0
### API calls using manually copied and shared variables
GET {{baseUrl}}/{{apiVersion}}/health
User-Agent: {{userAgent}}
4. Template Files for Team Sharing
Create template files that team members can copy and customize:
variables.template.http
(versioned):
# Copy this file to variables.local.http and fill in your values
@baseUrl = https://your-api-domain.com
@clientId = your-client-id-here
@clientSecret = your-client-secret-here
@tenantId = your-tenant-id-here
Team workflow: 1. Copy variables.template.http
to variables.local.http
2. Fill in actual values in variables.local.http
3. Copy and paste variables from variables.local.http
into your HTTP files as needed
5. VS Code Environment Variables (Recommended for Multiple Environments)
Instead of file imports, use VS Code’s built-in environment variable system for managing different environments:
In .vscode/settings.json
:
{
"rest-client.environmentVariables": {
"development": {
"baseUrl": "https://localhost:7001",
"apiKey": "dev-api-key-here"
},
"production": {
"baseUrl": "https://api.production.com",
"apiKey": "prod-api-key-here"
}
}
}
environment selection in vscode happens with Ctrl+Shift+P and selecting Rest Client: Switch Environment
Step | Screenshot |
---|---|
Ctrl+Shift+P | ![]() |
Rest Client: Switch Environment | ![]() |
In your HTTP files:
### Use environment variables (switch environments in VS Code status bar)
GET {{baseUrl}}/api/data
Authorization: Bearer {{apiKey}}
How to switch environments: 1. Look for No Environment
in VS Code status bar (bottom) 2. Click it to select development
or production
3. Variables automatically switch based on your selection
Best Practices for Variable Organization
Version Control Strategy: - ✅ DO commit: Template files, shared non-sensitive variables - ❌ DON’T commit: Environment-specific files with secrets, local customizations
File Naming Conventions: - *.template.http
- Template files for team sharing - *.env.http
- Environment-specific variables (add to .gitignore) - *.local.http
- Local developer overrides (add to .gitignore) - shared-*.http
- Common variables safe for version control
Security Guidelines: - Never commit API keys, passwords, or connection strings - Use placeholder values in template files - Document required variables in your README - Consider using VS Code’s built-in environment variables for sensitive data
Multiple Requests in One File
Separate requests with ###
:
### Get all items
GET {{baseUrl}}/items
### Get specific item
GET {{baseUrl}}/items/123
### Create new item
POST {{baseUrl}}/items
Content-Type: application/json
{
"name": "Test Item"
}
Response Handling
Store and use response values from previous requests.
The # @name
comment assigns a name to the request, allowing you to reference its response in subsequent requests:
### Create item and capture ID
# @name createItem
POST {{baseUrl}}/items
Content-Type: application/json
{
"name": "New Item"
}
### Get the created item using the response ID
GET {{baseUrl}}/items/{{createItem.response.body.id}}
How it works: - # @name createItem
assigns the name createItem
to the first request - When executed, the response is stored and can be referenced as createItem
- {createItem.response.body.id}
extracts the id
field from the response body - This allows you to chain requests where later requests depend on data from earlier ones
Response object structure: - createItem.response.body
- The response body (JSON object) - createItem.response.headers
- Response headers - createItem.response.status
- HTTP status code
Using Response Variables
### Login
# @name login
POST {{baseUrl}}/login
Content-Type: application/json
{
"username": "user",
"password": "pass"
}
### Use token from login response
GET {{baseUrl}}/secure-endpoint
Authorization: Bearer {{login.response.body.token}}
File Uploads
### Upload file
POST {{baseUrl}}/upload
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="test.txt"
Content-Type: text/plain
< ./test.txt
------WebKitFormBoundary7MA4YWxkTrZu0gW--
cURL Integration
The REST Client extension provides seamless integration with cURL, allowing you to import cURL commands or export your HTTP requests as cURL commands. This bidirectional conversion makes it easy to work with both formats.
Converting cURL to HTTP Files
You can paste cURL commands directly into your HTTP files, and the REST Client will understand and execute them:
### Direct cURL command in HTTP file
curl -X POST https://api.example.com/items \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {{token}}" \
-d '{"name": "Test Item", "description": "Created from cURL"}'
Alternative syntax - Convert cURL to standard HTTP format:
### Converted from cURL
POST https://api.example.com/items
Content-Type: application/json
Authorization: Bearer {{token}}
{
"name": "Test Item",
"description": "Created from cURL"
}
Exporting HTTP Requests as cURL
Right-click on any HTTP request in your file and select Copy Request as cURL
to get the equivalent cURL command. This is useful for:
- Sharing requests with team members who prefer command line
- Running requests in CI/CD pipelines
- Debugging requests in terminal environments
- Documentation that requires cURL examples
Example export result:
curl --request POST \
--url https://api.example.com/items \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer your-token-here' \
--data '{
"name": "Test Item",
"description": "Created from HTTP file"
}'
Using Variables with cURL
Variables defined in your HTTP files work seamlessly with both HTTP syntax and cURL commands:
@baseUrl = https://api.example.com
@authToken = Bearer abc123
### Using variables in cURL command
curl -X GET "{{baseUrl}}/items" \
-H "Authorization: {{authToken}}"
### Same request in HTTP syntax
GET {{baseUrl}}/items
Authorization: {{authToken}}
Advanced cURL Features Support
The REST Client supports most cURL features including:
File uploads:
curl -X POST "{{baseUrl}}/upload" \
-F "file=@./document.pdf" \
-F "description=Important document"
Custom headers and authentication:
curl -X GET "{{baseUrl}}/secure-data" \
-H "X-API-Key: {{apiKey}}" \
-H "User-Agent: MyApp/1.0" \
--basic -u "{{username}}:{{password}}"
Following redirects and handling cookies:
curl -X POST "{{baseUrl}}/login" \
-L \
-c cookies.txt \
-d "username={{user}}&password={{pass}}"
Supported cURL Options
The REST Client supports these commonly used cURL options:
cURL Option | Description | HTTP File Equivalent |
---|---|---|
-X, --request |
HTTP method | GET , POST , PUT , etc. |
-H, --header |
Custom headers | Header lines below method |
-d, --data |
Request body data | Body section after empty line |
-F, --form |
Form data | Content-Type: multipart/form-data |
-u, --user |
Basic authentication | Authorization: Basic header |
-b, --cookie |
Send cookies | Cookie: header |
-c, --cookie-jar |
Save cookies | Automatic cookie handling |
-L, --location |
Follow redirects | Automatic redirect following |
-k, --insecure |
Skip SSL verification | REST Client settings |
-v, --verbose |
Verbose output | Response details panel |
Benefits of cURL Integration
- Flexibility: Use whichever syntax you prefer - HTTP or cURL
- Team Compatibility: Easily share between HTTP file users and cURL users
- CI/CD Integration: Export requests for use in automated pipelines
- Legacy Support: Import existing cURL-based documentation and scripts
- Learning Bridge: Helps transition between command-line and GUI-based API testing
Best Practices for cURL Integration
- Use variables: Keep cURL commands maintainable with variable substitution
- Document both formats: Provide both HTTP and cURL examples in team documentation
- Consistent formatting: Use line continuation (
\
) for readable multi-line cURL commands - Environment awareness: Ensure variables work correctly when exporting to cURL
- Security: Be cautious when sharing exported cURL commands that might contain sensitive data
Benefits Over Postman
- Lightweight: No need for a separate application
- Version Control: Store API tests alongside your code
- Easy Sharing: Share requests as simple text files
- Environment Integration: Works directly in your development environment
- Text-based: Easy to review changes in pull requests
Azure AD Authentication for Protected APIs
When your API is protected by Azure AD authentication, you need to obtain an access token before making requests. Here are several approaches using HTTP files:
Method 1: Client Credentials Flow (Service-to-Service)
For service-to-service authentication using client credentials:
### Variables for Azure AD
@tenantId = b92a****-****-****-****-************
@clientId = 7cb9****-****-****-****-************
@clientSecret = your-client-secret-here
@scope = api://{{clientId}}/.default
@baseUrl = https://your-api-domain.com
### Get Azure AD Token (Client Credentials)
# @name getToken
POST https://login.microsoftonline.com/{{tenantId}}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id={{clientId}}
&client_secret={{clientSecret}}
&scope={{scope}}
### Use the token to call protected API
GET {{baseUrl}}/api/protected-endpoint
Authorization: Bearer {{getToken.response.body.access_token}}
Method 3: Using REST Client’s Built-in Azure AD Support
The REST Client extension has built-in support for Azure AD:
### Using system variable for Azure AD token
@tenantId = b92a****-****-****-****-************
@clientId = 7cb9****-****-****-****-************
### Call protected API with automatic token
GET {{baseUrl}}/api/protected-endpoint
Authorization: Bearer {{$aadToken tenantId clientId}}
Method 4: Environment-Specific Configuration
Create environment-specific configurations in VS Code settings:
In .vscode/settings.json
:
{
"rest-client.environmentVariables": {
"development": {
"baseUrl": "https://localhost:7001",
"tenantId": "b92a****-****-****-****-************",
"clientId": "7cb9****-****-****-****-************",
"clientSecret": "dev-client-secret"
},
"production": {
"baseUrl": "https://api.production.com",
"tenantId": "b92a****-****-****-****-************",
"clientId": "7cb9****-****-****-****-************",
"clientSecret": "prod-client-secret"
}
}
}
Then use in your HTTP file:
### Get token for current environment
# @name getEnvToken
POST https://login.microsoftonline.com/{{tenantId}}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id={{clientId}}
&client_secret={{clientSecret}}
&scope=api://{{clientId}}/.default
### Call API with environment-specific token
GET {{baseUrl}}/api/data
Authorization: Bearer {{getEnvToken.response.body.access_token}}
Method 5: Token Refresh Pattern
Handle token expiration with refresh tokens:
### Initial authentication
# @name initialAuth
POST https://login.microsoftonline.com/{{tenantId}}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id={{clientId}}
&code=AUTHORIZATION_CODE_HERE
&redirect_uri=http://localhost:8080/signin-oidc
&scope={{scope}}
### Refresh token when needed
# @name refreshAuth
POST https://login.microsoftonline.com/{{tenantId}}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&client_id={{clientId}}
&refresh_token={{initialAuth.response.body.refresh_token}}
&scope={{scope}}
### Use current valid token
GET {{baseUrl}}/api/secure-data
Authorization: Bearer {{refreshAuth.response.body.access_token}}
Security Best Practices
- Never commit secrets: Use environment variables or VS Code settings for sensitive data
- Token expiration: Check
expires_in
field and refresh tokens appropriately - Scope principle: Request only the minimum required scopes
- HTTPS only: Always use HTTPS for token requests
- Secure storage: Store tokens securely and clear them when done
Common Token Response Structure
Azure AD token responses typically include:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3599,
"refresh_token": "0.ARcA6KAC2wDFZEOPiD...",
"scope": "access_as_user"
}
You can reference these values in subsequent requests:
{tokenRequest.response.body.access_token}
{tokenRequest.response.body.expires_in}
{tokenRequest.response.body.refresh_token}
References
REST Client Extension Documentation
Official documentation from the extension author that provides detailed instructions on how to use the REST Client extension, including all available features and syntax options. Essential reading for understanding the full capabilities of the extension.VS Code REST Client GitHub Repository
The source repository contains examples, issue tracking, and the latest development updates for the extension. Useful for understanding the implementation details, finding solutions to common problems, and tracking feature requests.GitHub Issue #845: Support for including variables from separate files
This open issue discusses the requested feature for importing variables from external files using< ./file.http
syntax. Important for understanding current limitations and why file imports are not supported in the REST Client extension.Microsoft .http Files Documentation
Microsoft’s official documentation for .http files in Visual Studio and Visual Studio Code. Provides an alternative perspective on HTTP file usage, particularly useful for ASP.NET Core developers who want to understand Microsoft’s implementation and recommendations.HTTP/1.1 Specification (RFC 7230-7235)
The official HTTP protocol specification that defines the syntax and semantics of HTTP/1.1 messages. Understanding this specification helps write more accurate and standard-compliant HTTP requests and troubleshoot protocol-level issues.OAuth 2.0 Authorization Framework (RFC 6749)
The official OAuth 2.0 specification that defines the authorization framework used in the Azure AD authentication examples. Essential for understanding the security flows demonstrated in this guide.OAuth 2.0 for Public Clients (RFC 7636) - PKCE
The PKCE (Proof Key for Code Exchange) specification that extends OAuth 2.0 for enhanced security in public clients. Relevant for understanding the PKCE authentication flow examples provided in the Azure AD section.REST Client vs. Postman: A Comparative Analysis
An in-depth comparison between REST Client and other API testing tools like Postman, highlighting the strengths and limitations of each approach. Helps developers choose the right tool for their workflow.Advanced HTTP Request Testing Patterns
This guide covers advanced patterns for organizing and automating API tests using HTTP files, including environment management and test sequencing. Provides practical examples for complex testing scenarios.Environment Variables in REST Client
A specific guide on how to use environment variables in REST Client, which is crucial for managing different environments (development, testing, production) in your API tests. Direct reference to the official implementation details.cURL Manual and Documentation
Comprehensive documentation for cURL command-line tool. Relevant for understanding the cURL integration features demonstrated in this guide and for users transitioning between HTTP files and command-line tools.Azure Active Directory v2.0 Protocols
Microsoft’s documentation on Azure AD authentication protocols and endpoints. Essential reference for implementing the Azure AD authentication examples shown in this guide, including client credentials and PKCE flows.
Appendixes
Appendix A: REST Client Main Features
Feature Category | Feature | Purpose | How to Use |
---|---|---|---|
Request Execution | Send/Cancel/Rerun HTTP request | Execute HTTP requests directly in editor and view responses | Click Send Requestlink above request or use Ctrl+Alt+R |
Request Execution | View response in separate pane | Display formatted response with syntax highlighting | Response automatically appears in split pane after execution |
GraphQL Support | Send GraphQL queries | Execute GraphQL operations with variable support | Write GraphQL query in request body with variables section |
cURL Integration | Send cURL commands | Convert and execute cURL commands directly | Paste cURL command in .http file or copy request as cURL |
History Management | Auto save request history | Keep track of all executed requests | Access via command palette Rest Client: Request History |
Multi-Request Files | Compose multiple requests | Organize related API calls in single file | Separate requests with ### delimiter |
Response Handling | View image responses | Display images directly in response pane | Automatic for image content types |
Response Handling | Save responses to disk | Export response data for further analysis | Right-click response pane and select save options |
Response Formatting | Fold/unfold response body | Collapse/expand response sections | Click fold/unfold icons in response pane |
Response Formatting | Customize response font | Adjust readability of response display | Configure in VS Code settings under Rest Client |
Response Filtering | Preview specific response parts | Show only headers, body, or full response | Use response tabs (Headers/Body/Full) |
Authentication | Basic Auth support | Simple username/password authentication | Add Authorization: Basic base64(user:pass) header |
Authentication | Digest Auth support | More secure challenge-response authentication | Handled automatically when server requests digest auth |
Authentication | SSL Client Certificates | Certificate-based authentication | Configure in settings with certificate paths |
Authentication | Azure AD integration | Microsoft identity platform authentication | Use {$aadToken} system variable |
Authentication | AWS Signature v4 | AWS service authentication | Configure AWS credentials and use signature headers |
Variables | Environment variables | Manage different deployment environments | Define in .vscode/settings.json or environment files |
Variables | Custom variables | Reusable values throughout requests | Define with @variableName = value syntax |
Variables | System variables | Built-in dynamic values | Use {$guid} , {$timestamp} , etc. |
Variables | Prompt variables | Interactive input during execution | Define with @variable = {{$prompt variableName}} |
Variables | Auto-completion | IntelliSense for variables | Start typing {{ to see available variables |
Variables | Variable diagnostics | Error detection for undefined variables | Red underlines for missing variables |
Variables | Go to definition | Navigate to variable declarations | Ctrl+click on variable usage |
System Variables | GUID generation | Generate unique identifiers | {$guid} |
System Variables | Random integers | Generate random numbers in range | {$randomInt min max} |
System Variables | Timestamps | Current timestamp in various formats | {$timestamp} , {$datetime} |
System Variables | Environment access | Access system environment variables | {$processEnv variableName} |
System Variables | Dotenv support | Load variables from .env files | {$dotenv variableName} |
Environment Management | Environment switching | Switch between dev/test/prod configs | Use environment selector in status bar |
Environment Management | Shared environments | Common variables across environments | Define in shared environment section |
Code Generation | Generate code snippets | Convert requests to various languages | Right-click request and select Generate Code Snippet |
Session Management | Cookie persistence | Maintain session across requests | Automatic cookie handling between requests |
Network | Proxy support | Route requests through proxy servers | Configure proxy settings in VS Code |
SOAP Support | SOAP request support | Send SOAP web service requests | Use SOAP envelope templates and snippets |
Language Support | HTTP syntax highlighting | Color-coded request and response syntax | Automatic for .http and .rest files |
Language Support | Auto-completion | IntelliSense for HTTP methods, headers | Start typing to see suggestions |
Language Support | Comment support | Document requests with comments | Lines starting with # or // |
Language Support | JSON/XML formatting | Auto-indent and format request bodies | Automatic formatting for structured data |
Language Support | Code snippets | Quick templates for common requests | Type snippet name and press Tab |
Navigation | Symbol navigation | Jump to variable definitions | Use Go to Definition (F12) |
Navigation | CodeLens integration | Actionable links above requests | Click Send Requestlink |
Editor Features | Request folding | Collapse/expand request blocks | Click fold icons or use Ctrl+Shift+[ |
Markdown Integration | Fenced code blocks | HTTP requests in markdown files | Use ```http code blocks |